package com.my.algorithmlearning.leetcode;

import com.my.algorithmlearning.entity.TreeNode;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration;
import org.springframework.util.Assert;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;

/**
 * @ClassName InorderTraversal
 * @Description InorderTraversal
 * @Author wanghaiwei
 * @Date 2022/11/23 9:47
 */
public class PostorderTraversal {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        result.addAll(postorderTraversal(root.left));
        result.addAll(postorderTraversal(root.right));
        result.add(root.val);
        return result;
    }

    public List<Integer> postorderTraversalByIterator(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        Deque<TreeNode> traversalStack = new ArrayDeque<>();
        TreeNode currNode = root; //当前栈顶节点
        TreeNode childNode = root; //当前节点的子节点
        while(true) {
            if(currNode != null) {
                traversalStack.push(currNode);
                childNode = currNode;
                currNode = currNode.left;
            }else if(!traversalStack.isEmpty()){
                currNode = traversalStack.peek();
                //currNode.right == null表示当前节点没有右节点，currNode.right == preNode表示右节点已经弹出过
                if (currNode.right == null || currNode.right == childNode) {
                    result.add(currNode.val);
                    traversalStack.removeFirst();
                    childNode = currNode;
                    currNode = null;
                }else {
                    currNode = currNode.right;
                }
            }else {
                break;
            }
        }
        return result;
    }

    public boolean equalAssert(String expectedStr, List<Integer> result) {
        return expectedStr.equals(StringUtils.join(result, ','));
    }

    public static void main(String[] args) {
        PostorderTraversal solution = new PostorderTraversal();
        /*TreeNode root1 = new TreeNode(1);
        Assert.isTrue(solution.equalAssert("1", solution.postorderTraversal(root1)), "递归实现-[1]结果错误");
        Assert.isTrue(solution.equalAssert("1", solution.postorderTraversalByIterator(root1)), "迭代实现-[1]结果错误");
        TreeNode root2 = new TreeNode(1);
        root2.left = null;
        TreeNode right2 = new TreeNode(2);
        right2.left = new TreeNode(3);
        root2.right = right2;
        Assert.isTrue(solution.equalAssert("3,2,1", solution.postorderTraversal(root2)), "递归实现-[1,null,2,3]结果错误");
         */
        TreeNode root3 = new TreeNode(1);
        root3.left = null;
        TreeNode right3 = new TreeNode(2);
        right3.left = new TreeNode(3);
        root3.right = right3;
        List<Integer> result3 = solution.postorderTraversalByIterator(root3);
        Assert.isTrue(solution.equalAssert("3,2,1", result3), "迭代实现-[1,null,2,3]结果错误：" + StringUtils.join(result3,','));
    }
}
